﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using ImpactWorks.FBGraph.Connector;
using ImpactWorks.FBGraph.Core;
using ImpactWorks.FBGraph.Interfaces;
using PInitiatives.Helpers;
using PInitiatives.Models;
using PInitiatives.Outlook;
using PInitiatives.ViewModels.VMInitiative;

namespace PInitiatives.Controllers
{
    
    public class InitiativeController : Controller
    {
        private PInitiativesEntities _db = new PInitiativesEntities();

        //
        // GET: /Initiative/

        public ActionResult Index()
        {
            //var initiatives = db.Initiatives.Include(i => i.AutorInstance).Include(i => i.Categories);
            //return View(initiatives.ToList());
            return RedirectToAction("Browse");
        }

        //
        // GET: /Initiative/Details/5

        public ViewResult Details(int id, int category=0)
        {
            VMInitiativeDetails dvm = new VMInitiativeDetails();
            dvm.Initiative = _db.Initiatives.Find(id);
            dvm.Reviews = _db.Reviews.Where(un => un.InitiativeID == id);

            if(User.Identity.IsAuthenticated)
            {
                string userName = Membership.GetUser(User.Identity.Name, true /* userIsOnline */).UserName;
                User u = _db.Users.Single(user => user.aspnet_Users.UserName == userName);

            if (dvm.Initiative.getInitiativeUsers("Participated").Count() == 0)
                dvm.participates = false;
            else if (dvm.Initiative.getInitiativeUsers("Participated").SingleOrDefault(uu => uu.ID == u.ID) == null)
                dvm.participates = false;
            else
                dvm.participates = true;


            if (dvm.Initiative.InitiativeAuthor.aspnet_Users.UserName.Equals(userName))
                dvm.isAuthor = true;
            else
                dvm.isAuthor = false;
            }
            else
            {
                dvm.participates = false;
                dvm.isAuthor = false;
            }
            dvm.category = category;
            return View(dvm);
        }
        


        //
        // POST:
        [Authorize]
        [HttpPost]
        public ActionResult Details(string btnSubmit, VMInitiativeDetails dvm)
        {
            if (btnSubmit == "SendEmail")
            {
                return RedirectToAction("SendEmail", "Initiative", new { id = dvm.Initiative.ID});
            }
            if (btnSubmit == "CheckInCalendar")
            {
                try
                {
                    User currentUser = _db.Users.SingleOrDefault(u => u.aspnet_Users.UserName == User.Identity.Name);
                    Initiative initiative = _db.Initiatives.SingleOrDefault(i => i.ID == dvm.Initiative.ID);

                    OutlookMeetingGenerator.SendICalendarEmail(
                        initiative.StartDate,
                        initiative.StartDate.AddMinutes(30), //czas trwania incjatywy
                        currentUser.ID,
                        User.Identity.Name,
                        currentUser.Email,
                        initiative.ID,
                        initiative.InitiativeAuthor.UserName,
                        initiative.Name,
                        initiative.Description, //opis incjatywy, czy potrzebne ?
                        "lokalizacja"); //lokalizacja inicjatywy
                }
                catch
                {
                    return RedirectToAction("Error", "Shared");
                }

                return RedirectToAction("OutlookConfirm");

                #region OldApproach
                //if (initiative.getInitiativeUsers().Where(uu => uu.ID == currentUser.ID).Any())
                //{
                //    initiative.setInitiativeUsersStatus(currentUser, "WaitingForAccept");
                //}
                //else
                //{
                //    initiative.addInitiativeUsers(currentUser, "WaitingForAccept");
                //}

                //VMInitiativeDetails newDvm = new VMInitiativeDetails();
                //newDvm.participates = false;
                //newDvm.status = "WaitingForAccept";

                //_db.SaveChanges();
                //newDvm.Initiative = initiative;
                //newDvm.Reviews = _db.Reviews.Where(r => r.InitiativeID == initiative.ID);
                //return View(newDvm);
                #endregion
            }
            else
            {
                string userName = Membership.GetUser(User.Identity.Name, true /* userIsOnline */).UserName;
                User u = _db.Users.Single(user => user.aspnet_Users.UserName == userName);
                Initiative initiative = _db.Initiatives.Find(dvm.Initiative.ID);

                VMInitiativeDetails newDvm = new VMInitiativeDetails();

                if (Request["choice"].Equals("participate"))
                {
                    if (initiative.getInitiativeUsers().Where(uu => uu.ID == u.ID).Any())
                    {
                        initiative.setInitiativeUsersStatus(u, "Participated");
                    }
                    else
                    {
                        initiative.addInitiativeUsers(u);
                    }
                    newDvm.participates = true;
                    newDvm.status = "Participated";
                }
                else if (Request["choice"].Equals("resign"))
                {
                    initiative.setInitiativeUsersStatus(u, "Resigned");
                    if (DateTime.Now > initiative.FreeResignDate)
                        u.LMResignationsCount++;
                    else
                        u.ResignationsCount++;
                    newDvm.participates = false;
                    newDvm.status = "Resigned";
                }
                else if (Request["choice"].Equals("finish"))
                {
                    initiative.State = "Finished";
                    newDvm.participates = false;
                }
                else if (Request["choice"].Equals("cancel"))
                {
                    initiative.State = "Canceled";
                    u.CanceledInitiativesCount++;
                    newDvm.participates = false;
                }

                if (initiative.InitiativeAuthor.aspnet_Users.UserName.Equals(userName))
                    newDvm.isAuthor = true;
                else
                    newDvm.isAuthor = false;

                _db.SaveChanges();
                newDvm.Initiative = initiative;
                newDvm.Reviews = _db.Reviews.Where(r => r.InitiativeID == initiative.ID);
                return View(newDvm);
            }
        }
   

        //
        // GET: /Initiative/Browse

        public ViewResult Browse(int category = 0, string searchString = "", string startDateFrom = "", string status = "", int created = 0, int participated = 0)
        {

            var bvm = new VMInitiativeBrowse();

            ViewBag.Status = new SelectList(StatusHelper.getStatusesPL());

            if (User.Identity.IsAuthenticated)
            {
                bvm.userName = Membership.GetUser(User.Identity.Name, true /* userIsOnline */).UserName;
            }else{

                bvm.userName = null;
            }

            //int initiativesPerPage = 5;
            //bad page
            //if (page < 1) page = 1;

            //bvm.page = page;
            //bvm.orderBy = orderBy;
            //bvm.orderRule = orderRule;
            
            //bvm.category = category;
            //bvm.searchString = searchString;

            #region Old approach for /get initatives/
            //no such category
            //if (_db.Categories.Where(c => c.ID == category).Count() == 0)
            //    category = 0;

            //count initiatives in each branch
            //foreach (Category c in db.Categories)
            //    c.CountInitiativesOwn();

            //estimate and send initiatives from the category
            //var initiatives = db.CategoryDependences.Where(c => c.Ancestor == category).
            //    Join(db.Initiatives, c => c.Descendant, i => i.Category, (u, i) => i).Where(i => i.Name.Contains(searchString));
            #endregion

            Category selectedCategory = _db.Categories.SingleOrDefault(c => c.ID == category);
            if (selectedCategory == null)
                selectedCategory = _db.Categories.Single(c => c.Parent == null);

            var initiatives = selectedCategory.GetAllInitativesInBranch();

            string statusEN = StatusHelper.getStatusEN(status);
            initiatives = initiatives.Where(i => (i.Name.Contains(searchString)));
            if (!status.Equals(""))
                initiatives = initiatives.Where(i => (i.State.Equals(statusEN)));
            //if (created != 0 && bvm.userName!=null)
            //{
            //    initiatives = initiatives.Where(i => (i.InitiativeAuthor.UserName.Equals(bvm.userName)));
            //}

            #region Old approach for /ordering/
            //if (orderRule == 0)
            //{
            //    if (orderBy.Equals("IDescription"))
            //        initiatives = initiatives.OrderBy(i => i.Description);
            //    else if (orderBy.Equals("IAuthor"))
            //        initiatives = initiatives.OrderBy(i => i.InitiativeAuthor.LastName);
            //    else if (orderBy.Equals("ICategory"))
            //        initiatives = initiatives.OrderBy(i => i.Category);
            //    else if (orderBy.Equals("IStartDate"))
            //        initiatives = initiatives.OrderBy(i => i.StartDate);
            //    else if (orderBy.Equals("ICreateDate"))
            //        initiatives = initiatives.OrderBy(i => i.CreateDate);
            //    else if (orderBy.Equals("IState"))
            //        initiatives = initiatives.OrderBy(i => i.State);
            //    else if (orderBy.Equals("IFreeResignDate"))
            //        initiatives = initiatives.OrderBy(i => i.FreeResignDate);
            //    else if (orderBy.Equals("ILimit"))
            //        initiatives = initiatives.OrderBy(i => i.InitiativeUsers.Count);
            //    else
            //        initiatives = initiatives.OrderBy(i => i.Name);
            //}
            //else
            //{
            //    if (orderBy.Equals("IDescription"))
            //        initiatives = initiatives.OrderByDescending(i => i.Description);
            //    else if (orderBy.Equals("IAuthor"))
            //        initiatives = initiatives.OrderByDescending(i => i.InitiativeAuthor.LastName);
            //    else if (orderBy.Equals("ICategory"))
            //        initiatives = initiatives.OrderByDescending(i => i.Category);
            //    else if (orderBy.Equals("IStartDate"))
            //        initiatives = initiatives.OrderByDescending(i => i.StartDate);
            //    else if (orderBy.Equals("ICreateDate"))
            //        initiatives = initiatives.OrderByDescending(i => i.CreateDate);
            //    else if (orderBy.Equals("IState"))
            //        initiatives = initiatives.OrderByDescending(i => i.State);
            //    else if (orderBy.Equals("IFreeResignDate"))
            //        initiatives = initiatives.OrderByDescending(i => i.FreeResignDate);
            //    else if (orderBy.Equals("ILimit"))
            //        initiatives = initiatives.OrderByDescending(i => i.InitiativeUsers.Count);
            //    else
            //        initiatives = initiatives.OrderByDescending(i => i.Name);
            //}
            #endregion Old approach for /ordering/

            #region Old approach for /pages/
            //if (initiatives.Count() <= (page - 1) * initiativesPerPage)
            //{
            //    page = (initiatives.Count()-1) / initiativesPerPage+1;
            //     bvm.page = page;
            //}
            //bvm.Initiatives = initiatives.Skip((page - 1) * initiativesPerPage).Take(initiativesPerPage);
            #endregion Old approach for /pages/

            //send list of categoriesale 
            var categories = _db.Categories.Include(c => c.ChildCategories);

            //send both    
            bvm.category = category;
            bvm.Initiatives = initiatives;
            bvm.Categories = categories;
            return View(bvm);


        }

                

        //
        // GET: /Initiative/Create
        [Authorize]
        public ActionResult Create()
        {
            ViewBag.Category = new SelectList(CategoryManager.GetCategoryDDL(), "ID", "Name");
            //ViewBag.Category = new SelectList(_db.Categories, "ID", "Name", 8);
            //ViewBag.State = new SelectList(_db.Dictionaries.Where(d => d.DictionaryName.Equals("InitiativeStatus")).Select(d => d.DictionaryValue));
            return View();
        }

        ////
        //// POST: /Initiative/Create
        //[Authorize]
        //[HttpPost]
        //public ActionResult Create(Initiative initiative)
        //{
        //    string userName = Membership.GetUser(User.Identity.Name, true /* userIsOnline */).UserName;
        //    User u = _db.Users.Single(user => user.aspnet_Users.UserName == userName);
        //    initiative.AutorInstance = u;
        //    initiative.InitiativeUsers.Add(u);
        //    initiative.CreateDate = DateTime.Now;
        //    _db.Initiatives.Add(initiative);
        //    _db.SaveChanges();
        //    return RedirectToAction("Details", new { id = initiative.ID });
        //}

        // POST: /Initiative/Create
        [Authorize]
        [HttpPost]
        public ActionResult Create(CreateInitiativeModel model)
        {
            if (ModelState.IsValid)
            {
                string userName = Membership.GetUser(User.Identity.Name, true /* userIsOnline */).UserName;
                User u = _db.Users.Single(user => user.aspnet_Users.UserName == userName);
                Initiative initiative = new Initiative();
                initiative.Name = model.Name;
                if (!string.IsNullOrEmpty(model.Description))
                    initiative.Description = model.Description;
                else
                    initiative.Description = "";
                initiative.Limit = model.Limit;
                initiative.Category = model.Category;
                initiative.CreateDate = DateTime.Now;
                initiative.StartDate = DateTime.Parse(model.StartDate);
                if (initiative.StartDate < DateTime.Now)
                {
                    initiative.StartDate = DateTime.Now.AddSeconds(60 - DateTime.Now.Second);
                }
                initiative.FreeResignDate = DateTime.Parse(model.FreeResignDate);
                if (initiative.FreeResignDate < DateTime.Now)
                {
                    initiative.FreeResignDate = DateTime.Now.AddSeconds(60 - DateTime.Now.Second);
                }
                if (initiative.FreeResignDate > initiative.StartDate)
                {
                    initiative.FreeResignDate = initiative.StartDate;
                }
                initiative.State = "Active";
                initiative.Autor = u.ID;
                _db.Initiatives.Add(initiative);
                _db.SaveChanges();


                if (UserHelper.GetCurrentUser().PostOnFB == true)
                    return RedirectToAction("NewFacebookMsg", new { id = initiative.ID });
                else
                    return RedirectToAction("Details", new { id = initiative.ID });
            }
            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Initiative/Edit/5
        [InitiativeAccessDeniedAuthorize]
        public ActionResult Edit(int id)
        {
            Initiative initiative = _db.Initiatives.Find(id);
            ViewBag.Category = new SelectList(_db.Categories, "ID", "Name", initiative.Category);
            //ViewBag.State = new SelectList(Dictionary.getRows("InitiativeStatus").Select(d => d.DictionaryValue), initiative.State);
            
            //ViewBag.State = new SelectList(_db.Dictionaries.Where(d => d.DictionaryName.Equals("InitiativeStatus")).Select(d => d.DictionaryValue), initiative.State);
            return View(initiative);


        }

        //
        // POST: /Initiative/Edit/5

        [InitiativeAccessDeniedAuthorize]
        [HttpPost]
        public ActionResult Edit(Initiative initiative)
        {
            if (ModelState.IsValid)
            {
                _db.Entry(initiative).State = EntityState.Modified;
                _db.SaveChanges();
                return RedirectToAction("Details", new { id = initiative.ID });
            }
            ViewBag.Category = new SelectList(_db.Categories, "ID", "Name", initiative.Category);
            
            //ViewBag.State = new SelectList(Dictionary.getRows("InitiativeStatus").Select(d => d.DictionaryValue), initiative.State);
            return View(initiative);
        }

        //
        // GET: /Initiative/Delete/5
 
        public ActionResult Delete(int id)
        {
            Initiative initiative = _db.Initiatives.Find(id);
            return View(initiative);
        }

        //
        // POST: /Initiative/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {            
            Initiative initiative = _db.Initiatives.Find(id);
            while (initiative.getInitiativeUsers("Participated").Count<User>() > 0)
            {
                initiative.setInitiativeUsersStatus(initiative.getInitiativeUsers("Participated").First(), "Resigned");
            }
            _db.Initiatives.Remove(initiative);
            _db.SaveChanges();
            return RedirectToAction("Index");
        }


        protected override void Dispose(bool disposing)
        {
            _db.Dispose();
            base.Dispose(disposing);
        }

        public ActionResult OutlookConfirm()
        {
            return View();
        }

        #region SendEmail
        public ActionResult SendEmail(int id)
        {
            Initiative initiative = _db.Initiatives.SingleOrDefault(i => i.ID == id);
            VMInitiativeSendEmail sendEmail = new VMInitiativeSendEmail();
            sendEmail.Initiative = initiative;
            sendEmail.Subject = "Pytanie o ivent: " + initiative.Name;
            sendEmail.Message = "Witam, \n piszę z portalu ivent.pl ......";
            return View(sendEmail);

        }

        [Authorize]
        [HttpPost]
        public ActionResult SendEmail(int id, VMInitiativeSendEmail sendEmailVM)
        {
            Initiative initative = _db.Initiatives.SingleOrDefault(i => i.ID == id);
            Email.SendEmail(initative.InitiativeAuthor.Email, sendEmailVM.Subject, sendEmailVM.Message + "\nProszę o kontakt: " + UserHelper.GetCurrentUser().Email);
            return RedirectToAction("Details", "Initiative", new { id = initative.ID });
        }
        #endregion


        #region Facebook
        public ActionResult NewFacebookMsg(int id, string code)
        {
            Facebook facebook = new Facebook();
            facebook.AppID = SettingsManager.GetSettingValue("Facebook.AppID");
            facebook.Secret = SettingsManager.GetSettingValue("Facebook.Secret");

            if (string.IsNullOrEmpty(code))
                facebook.CallBackURL = Request.Url.AbsoluteUri;
            else
                facebook.CallBackURL = Request.Url.AbsoluteUri.Split('?')[0];

            List<FBPermissions> permissions = new List<FBPermissions>() {
                    FBPermissions.read_stream,
                    FBPermissions.publish_stream 
                };
            facebook.Permissions = permissions;
            
            if (String.IsNullOrEmpty(Request.QueryString["code"]))
            {
                String authLink = facebook.GetAuthorizationLink();
                //Response.Redirect(authLink);
                return Redirect(authLink);
            }
            else
            {
                facebook.GetAccessToken(Request.QueryString["code"]);
                FBUser currentUser = facebook.GetLoggedInUserInfo();
                IFeedPost FBpost = new FeedPost();

                PInitiativesEntities db = new PInitiativesEntities();
                Initiative ini = db.Initiatives.SingleOrDefault(i => i.ID == id);
                FBpost.Caption = "Data rozpoczęcia: " + ini.StartDate;
                //FBpost.Description = "Opis";
                FBpost.Name = ini.Name;
                FBpost.Url = "http://localhost:1369/Initiative/Details/" + ini.ID.ToString();
                FBpost.Message = "Organizuje Nowy Ivent\n";
                FBpost.Description = ini.Description;

                var postID = facebook.PostToWall(currentUser.id.GetValueOrDefault(), FBpost);
                return RedirectToAction("Details", new { id = id });
            }
        }
        #endregion

    }
}